#include "dvbinner.h"

unsigned int DVBGetServiceIndex(dvb_service_t* handle)
{
	unsigned int i;
	unsigned int u32Index = 0;
	dvb_group_t* pstGroup;
	
	pstGroup = DVBGetCurGroup();
	if(pstGroup)
	{
		for(i=0; i<pstGroup->serviceCount; i++)
		{
			if((pstGroup->Services[i].netId==handle->netId) && (pstGroup->Services[i].tsId==handle->tsId)
				&& (pstGroup->Services[i].serviceId==handle->serviceId) && (pstGroup->Services[i].frequence==handle->frequence))
			{
				u32Index = i+1;
				break;
			}
		}
	}

	return u32Index;
}

int DVBGetServiceType(dvb_service_t* handle, unsigned int* pu32Type)
{
	sipsi_dvbservice_t svr;
	unsigned char *p;
	int rc;

	rc = DVBTSGetServiceType(handle, pu32Type);
	if(rc == -1)
	{
		rc = DVBServicesDBGetType(handle, pu32Type);
	}
	
	return rc;
}

int DVBIsServiceEncrypt(dvb_service_t* handle)
{
	PIDINFO pidinfo[20];
	int i,count;

	if (!handle)		return -1;

	count = DVBTSGetServicePmtPids(handle,pidinfo);
	for (i=0;	i<MIN(count,20);	i++)
	{
		if (pidinfo[i].ecmNum!=0)
			return 1;
	}
	return 0;
}

int DVBServiceSetAudioIndex(dvb_service_t* handle, unsigned int index)
{
	AUDIOLANGINFO audioLangInfo[20];
	unsigned int num = 20;
	int ret;
	
	ret = DVBServiceGetAudioLangInfo(handle, audioLangInfo, &num);
	if(!ret && index<num)
	{
		unsigned int pcrPID;
		unsigned int vid;
		int elementCnt;
		unsigned int aid[16];
		unsigned int aPid;
		unsigned int aType;

		if(DVBServicesDBGetAudioIndex(handle) == index)
		{
			return -1;
		}
		
		pcrPID = 0;
		vid = 0;
		memset(aid, 0, sizeof(aid));
		elementCnt = DVBTSGetServicePIDSEx(handle,&pcrPID,&vid,aid);
		mwDebug("DVBServiceSetAudioIndex() - elementCnt=%d", elementCnt);
		if(elementCnt>1)
		{
			if(index > elementCnt-3)
				index = 0;
			aPid = (aid[index]&0x1fff);
			aType = (aid[index]>>16);
			mwDebug("DVBServiceSetAudioIndex() - aPid=%d,aType=%d", aPid,aType);			
			mwAvSwitchAudio(aPid,aType);
		}
		DVBServicesDBSetAudioIndex(handle, index);
		return 0;
	}
	else
		return -1;
}

int DvbServiceSetTuner(dvb_service_t* handle)
{
	dvb_tuner_t stTunerInfo;
	int s32Ret = -1;

	s32Ret = DVBTSGetTunerInfoByServiceHandle(handle, &stTunerInfo);
	if(s32Ret == 0)
	{
		s32Ret = DVBTunerLock(&stTunerInfo);
	}
	return s32Ret;
}

int DVBGetServiceTunerInfo(dvb_service_t* handle, dvb_tuner_t* pstTunerInfo)
{
	int s32Ret = -1;

	s32Ret = DVBTSGetTunerInfoByServiceHandle(handle, pstTunerInfo);

	return s32Ret;
	
}

int DVBServicePlay(int hPlay, dvb_service_t* handle, pServicePlayNotify callback)
{
	unsigned int pcrPID,vid,aid[16],ECM_PID=0;
	TSDATA *ts;
	int ret;
	int elementCnt;
	dvb_group_t* pCurGroup;
	int i;
	int stereoMode, vol;
	play_control_param_t playParam;
	dvb_tuner_t stTunerInfo;
	unsigned int u32AudioIndex = 0;
	int s32Ret = -1;

	g_hPlay = hPlay;	
	if(handle)
	{
		mwDebug("DVBServicePlay() - play handle[%d, %d, %d,%d]\n", handle->netId, handle->tsId, handle->serviceId,handle->frequence);
		pCurGroup = DVBGetCurGroup();
		if(pCurGroup)
		{
			for(i=0; i<pCurGroup->serviceCount; i++)
			{
				if(handle->netId==pCurGroup->Services[i].netId && handle->tsId==pCurGroup->Services[i].tsId
					&& handle->serviceId==pCurGroup->Services[i].serviceId && handle->frequence==pCurGroup->Services[i].frequence)
				{
					break;
				}
			}
			if(i < pCurGroup->serviceCount)
			{
				pCurGroup->Curno = i;
				s32Ret = DVBTSGetTunerParam(handle, &stTunerInfo);
				if(s32Ret == 0)
				{
					DvbSetCurService(handle);
					stereoMode = DVBServicesDBGetStereoMode(handle);
					vol = DVBServicesDBGetVolume(handle);
					memset(&playParam,0,sizeof(playParam));
					u32AudioIndex = DVBServicesDBGetAudioIndex(handle);
					ret = DVBTSGetPmt(handle, playParam.pmt, &playParam.pmtlen);
					if(ret == 0)//prog with pmt
					{
						memcpy(&playParam.tunerInfo, &stTunerInfo, sizeof(dvb_tuner_t));
						pcrPID = 0;
						vid = 0;
						memset(aid, 0, sizeof(aid));
						elementCnt = DVBTSGetServicePIDSEx(handle, &pcrPID, &vid, aid);
						mwDebug("DvgServicePlay() - handle->serviceId = %d,  elementCnt=%d",  handle->serviceId, elementCnt);
						if(elementCnt>1)
						{
							playParam.stero = stereoMode;
							playParam.vol = vol;
							playParam.vPid = (unsigned short)(vid&0x1fff);
							playParam.vType = (unsigned short)((vid>>16)&0xffff);
							
							if(u32AudioIndex > elementCnt-2)
								u32AudioIndex = 0;
							playParam.aPid = (unsigned short)(aid[u32AudioIndex]&0x1fff);
							playParam.aType = (unsigned short)(aid[u32AudioIndex]>>16);
							playParam.pPid = (unsigned short)pcrPID;
							playParam.handle.frequence = handle->frequence;
							playParam.handle.netId= handle->netId;
							playParam.handle.serviceId = handle->serviceId;
							playParam.handle.tsId = handle->tsId;
							playParam.callback = callback;
							playParam.pmtpid = 0x1FFF;
							DVBTSGetPmtPid(handle, &playParam.pmtpid);
							ret = DvbPlayNewChannel(&playParam);
						}
						else
						{
							mwDebug("Service Element Not Found\n");
							ret = -1;
						}
					}
					else
					{
						playParam.callback = callback;
						playParam.handle.frequence = handle->frequence;
						playParam.handle.netId = handle->netId;
						playParam.handle.serviceId = handle->serviceId;
						playParam.handle.tsId = handle->tsId;
						playParam.stero = stereoMode;
						memcpy(&playParam.tunerInfo, &ts->tunerParams, sizeof(dvb_tuner_t));
						playParam.vol = vol;
						playParam.pmtpid = 0;//no pmt
						mwDebug("DVBServicePlay() - net prog handle[%d, %d, %d, %d]", handle->frequence, handle->netId, handle->tsId, handle->serviceId);
						ret = DvbPlayNewChannel(&playParam);
					}
					newChannel = 1;
				}
				else
				{
					mwError("DVBServicePlay() - get tuner param failed\r\n");
				}

			}
			else
			{
				mwError("DVBServicePlay() handle not found in cur group\r\n");
			}
		}
		else
		{
			mwError("DVBServicePlay() - CurGroup = NULL\r\n");
		}
	}
	else
	{
		mwError("DVBServicePlay() - receive null handle. \r\n");
	}
	
	if(callback && ret == -1)
		callback(0, handle);
	return ret;
} 

int DVBServicePlayNext(int hPlay,pServicePlayNotify callback)
{
	dvb_group_t* pCurGroup;
	dvb_service_t* handle;
	
	mwDebug("DVBServicePlayNext() - entry\r\n");
	pCurGroup = DVBGetCurGroup();
	if(!pCurGroup)
	{
		mwError("DVBServicePlayNext() - found cur group NULL\r\n");
		return -1;
	}
	pCurGroup->Curno++;
	pCurGroup->Curno %= pCurGroup->serviceCount;
	handle = &pCurGroup->Services[pCurGroup->Curno];
	return DVBServicePlay(hPlay,handle, callback);
}

int DVBServicePlayPrevious(int hPlay,pServicePlayNotify callback)
{
	dvb_group_t* pCurGroup;
	dvb_service_t* handle;

	mwDebug("DVBServicePlayPrevious() - entry\r\n");
	pCurGroup = DVBGetCurGroup();
	if(!pCurGroup)
	{
		mwError("DVBServicePlayPrevious() - found cur group NULL\r\n");
		return -1;
	}

	if(pCurGroup->Curno)
		pCurGroup->Curno--;
	else
		pCurGroup->Curno = pCurGroup->serviceCount -1;
	handle = &pCurGroup->Services[pCurGroup->Curno];

	return DVBServicePlay(hPlay,handle, callback);
}

int DVBServicePlayByIndex(int hPlay,unsigned short index, pServicePlayNotify callback)
{
	dvb_group_t* pCurGroup;
	dvb_service_t* handle;

	mwDebug("DVBServicePlayByIndex() - entry, index = %d\r\n", index);
	pCurGroup = DVBGetCurGroup();
	if(!pCurGroup)
	{
		mwError("DVBServicePlayByIndex() -  found cur group NULL\r\n");
		return -1;
	}
	if(index<pCurGroup->serviceCount)
	{
		mwDebug("DVBServicePlayByIndex() -  pCurGroup->serviceCount=%D\r\n", pCurGroup->serviceCount);
		pCurGroup->Curno = index;
		handle = &pCurGroup->Services[index];
		return DVBServicePlay(hPlay,handle, callback);
	}
	return -1;
}

int DVBServicePlayLast(int hPlay,pServicePlayNotify callback)
{
	dvb_group_t* pCurGroup;
	dvb_service_t sd;
	dvb_service_t last;

	mwDebug("DVBServicePlayLast() - call\r\n");
	pCurGroup = DVBGetCurGroup();
	if(!pCurGroup)
	{
		mwError("DVBServicePlayLast() -  found cur group NULL\r\n");
		return -1;
	}

	last = DvbGetLastService();
	if(DvbCheckServiceHandle(&last) == -1)//invalid service handle
	{
		mwError("DVBServicePlayLast() -  found invalid handle\r\n");
		return -1;
	}
	
	sd = DvbGetCurService();
	if(last.frequence == sd.frequence && last.netId == sd.netId
			&& last.serviceId == sd.serviceId && last.tsId == sd.tsId)
	{
		return -1;
	}

	return DVBServicePlay(hPlay, &last, callback);
}

int DVBServicePlayStop(int hPlay)
{
	int ret = 0;
	g_hPlay = hPlay;
	ret = DvbPlayStop();
	if(ret != 0)
		mwError("DVBServicePlayStop() - call DvbPlayStop version 1 not OK\r\n");
	
	return ret;
}

int DVBServiceGetIndexByTsidAndServiceid(unsigned short network_id, unsigned short ts_id, unsigned short service_id)
{
	dvb_group_t* pCurGroup;
	dvb_service_t* handle;
	unsigned short i;
	int s32Index = -1;

	pCurGroup = DVBGetCurGroup();
	if(!pCurGroup)
	{
		mwError("[ERROR] %s() -  found cur group NULL", __FUNCTION__);
		return -1;
	}
	
	s32Index = DVBGroupFindItemByTsidAndServiceid(pCurGroup, network_id, ts_id, service_id);
	
	return s32Index;
}

static int s_sourceType = 1; //0 -t,1 -c

int DVBSetInSourceType(int type)
{
	mwDebug("DVBSetInSourceType type = %d\r\n", type);
	s_sourceType = type;
	return 0;
}

int DVBTunerLock(dvb_tuner_t* params)
{
	if(s_sourceType == 0)
	{
		params->symbol_rate = 0;
		params->modulation = 0;
		params->tunertype = 0;
	}

	return mwTunerLock(params, 0);
}

int DVBTunerForceLock(dvb_tuner_t* params)
{
	if(s_sourceType == 0)
	{
		params->symbol_rate = 0;
		params->modulation = 0;
		params->tunertype = 0;
	}
	return mwTunerLock(params, 1);
}

int DVBGetSignalStatus(dvb_tuner_status_t *status)
{
	return mwTunerGetStatus(status);
}

int DVBTunerStandby()
{
	int ret;
	
	ret = mwTunerStandby();
	
	return ret;
}

int DVBTunerResume()
{
	int ret;

	//ret = mwTunerResume();
	ret = mwTunerReset(0);

	return ret;
}

int DVBTunerReset()
{
	int ret;
	
	ret = mwTunerReset(0);

	return ret;
}

int DVBGetMagicId()
{
	int u32MagicId = -1;

	u32MagicId = DvbBuilderGetPluginMagicId();
	
	return u32MagicId;
}

unsigned char u8Discrambling;
void DVBServiceDescrambling()
{
	u8Discrambling = 1;
}

int DVBServiceDescrambleCheckByIndex(unsigned int u32Index)
{
	int s32Ret = -1;
	unsigned int u32Times;
	
	s32Ret = DVBServicePlayByIndex(1, u32Index, NULL);
	if(s32Ret == 0)
	{
		u32Times = 0;
		u8Discrambling = 0;
		do
		{
			u32Times++;
			mwOsSleep(100);
		}while(u8Discrambling == 0 && u32Times < 15);

		if(u8Discrambling == 1)
		{
			s32Ret = 1;
		}
		DVBServicePlayStop(0);
	}
	return s32Ret;
}

int DVBSetDemoParam(dvb_demo_param_t* pstParam, unsigned int u32Num)
{
	int s32Ret = -1;

	mwDebug("DVBSetDemoParam() - entry, pstParam = %p, u32Num = %d\r\n", pstParam, u32Num);
	s32Ret = mwTunerDemoModeSetParam(pstParam, u32Num);
	
	return s32Ret;
}

unsigned int DVBStringLen(char* ps8String)
{
	unsigned int u32Len = 0;

	if(ps8String)
	{
		if(ps8String[0] == 0x11)
		{
			u32Len = 1;
			do
			{
				if(ps8String[u32Len]==0 && ps8String[u32Len+1]==0)
					break;
				u32Len += 2;
			}while(u32Len < 32);
		}
		else
		{
			u32Len = strlen(ps8String);
		}
	}
	
	return u32Len;
}

int DVBGetServiceName(dvb_service_t* handle, char*provider, char*sname)
{
	sipsi_dvbservice_t svr;
	int ret;
	unsigned int u32NetUpdated = 0;
	unsigned short u16ProviderNameLen;
	unsigned short u16ServiceNameLen;
	
	ret = DvbServicesDBGetName(handle, provider, sname);
	if(ret == 0)
	{
		
	}
	else
	{
		ret = DVBTSGetServiceInfo(handle, &svr);
		if(ret==0)
		{
			if(svr.m_pu8Descriptors)
			{
				SiPsiSDTGetServiceName(&svr, provider, &u16ProviderNameLen, sname, &u16ServiceNameLen, sys_lan);
				if(provider)
				{
					mwConvertString(provider, u16ProviderNameLen, sys_lan);
				}
				if(sname)
				{
					mwConvertString(sname, u16ServiceNameLen, sys_lan);
				}
			}
			else
				sprintf(sname, "unknown name%d", handle->serviceId);
		}
	}
	return ret;
}

